﻿'Copyright (c) Microsoft Corporation.  All rights reserved.


Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.Drawing
Imports System.Windows.Forms
Imports Microsoft.WindowsAPICodePack.Shell
Imports System.IO
Imports System.Diagnostics

Namespace Microsoft.WindowsAPICodePack.Samples.ShellObjectCFDBrowser
	Partial Public Class Form1
		Inherits Form
		Private currentlySelected As ShellObject = Nothing

		Public Sub New()
			InitializeComponent()

			LoadKnownFolders()
			LoadSavedSearches()

			If CoreHelpers.RunningOnWin7 Then
				LoadKnownLibraries()
			Else
				librariesComboBox.Enabled = False
				cfdLibraryButton.Enabled = librariesComboBox.Enabled
				label2.Enabled = cfdLibraryButton.Enabled
			End If

			If CoreHelpers.RunningOnWin7 Then
				LoadSearchConnectors()
			Else
				searchConnectorComboBox.Enabled = False
				searchConnectorButton.Enabled = searchConnectorComboBox.Enabled
				label7.Enabled = searchConnectorButton.Enabled
			End If
		End Sub

		''' <summary>
		''' Load all the Saved Searches on the current system
		''' </summary>
		Private Sub LoadSavedSearches()
			For Each so As ShellObject In KnownFolders.SavedSearches
				If TypeOf so Is SavedSearch Then
					savedSearchComboBox.Items.Add(Path.GetFileName(so.ParsingName))
				End If
			Next so

			If savedSearchComboBox.Items.Count > 0 Then
				savedSearchComboBox.SelectedIndex = 0
			Else
				savedSearchButton.Enabled = False
			End If
		End Sub

		''' <summary>
		''' Load all the Search Connectors on the current system
		''' </summary>
		Private Sub LoadSearchConnectors()
			For Each so As ShellObject In KnownFolders.SavedSearches
				If TypeOf so Is SearchConnector Then
					searchConnectorComboBox.Items.Add(Path.GetFileName(so.ParsingName))
				End If
			Next so

			If searchConnectorComboBox.Items.Count > 0 Then
				searchConnectorComboBox.SelectedIndex = 0
			Else
				searchConnectorButton.Enabled = False
			End If
		End Sub

		''' <summary>
		''' Load the known Shell Libraries
		''' </summary>
		Private Sub LoadKnownLibraries()
			' Load all the known libraries.
			' (There's currently no easy way to get all the known libraries in the system, 
			' so hard-code them here.)

			' Make sure we are clear
			librariesComboBox.Items.Clear()

			' 
			librariesComboBox.Items.Add("Documents")
			librariesComboBox.Items.Add("Music")
			librariesComboBox.Items.Add("Pictures")
			librariesComboBox.Items.Add("Videos")

			' Set initial selection
			librariesComboBox.SelectedIndex = 0
		End Sub

		''' <summary>
		''' Load all the knownfolders into the combobox
		''' </summary>
		Private Sub LoadKnownFolders()
			' Make sure we are clear
			knownFoldersComboBox.Items.Clear()

			' Get a list of all the known folders
			For Each kf As IKnownFolder In KnownFolders.All
				If kf IsNot Nothing AndAlso kf.CanonicalName IsNot Nothing Then
					knownFoldersComboBox.Items.Add(kf.CanonicalName)
				End If
			Next kf

			' Set our initial selection
			If knownFoldersComboBox.Items.Count > 0 Then
				knownFoldersComboBox.SelectedIndex = 0
			End If
		End Sub

		Private Sub cfdKFButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles cfdKFButton.Click
			' Initialize
			detailsListView.Items.Clear()
			pictureBox1.Image = Nothing

			' Create a new CFD
			Dim cfd As New CommonOpenFileDialog()

			' Allow users to select non-filesystem objects
			cfd.AllowNonFileSystemItems = True
			cfd.CheckReadOnly = True

			' Get the known folder selected
			Dim kfString As String = TryCast(knownFoldersComboBox.SelectedItem, String)

			If (Not String.IsNullOrEmpty(kfString)) Then
				Try
					' Try to get a known folder using the selected item (string).
					Dim kf As IKnownFolder = KnownFolderHelper.FromCanonicalName(kfString)

					' Set the knownfolder in the CFD.
					cfd.InitialLocation = TryCast(kf, ShellContainer)

					If (Not cfd.ShowDialog().Canceled) Then
						Dim selectedSO As ShellObject = Nothing

						Try
							' Get the selection from the user.
							selectedSO = cfd.Item
						Catch
							' In some cases the user might select an object that cannot be wrapped
							' by ShellObject.
							MessageBox.Show("Could not create a ShellObject from the selected item.")
						End Try


						currentlySelected = selectedSO

						DisplayProperties(selectedSO)

						showChildItemsButton.Enabled = If(TypeOf selectedSO Is ShellContainer, True, False)
					End If
				Catch
					MessageBox.Show("Could not create a KnownFolder object for the selected item")
				End Try
			Else
				MessageBox.Show("Invalid KnownFolder set.")
			End If

			' Dispose our dialog in the end
			cfd.Dispose()
		End Sub

		Private Sub cfdLibraryButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles cfdLibraryButton.Click
			' Initialize
			detailsListView.Items.Clear()
			pictureBox1.Image = Nothing

			' If the user has selected a library,
			' try to get the known folder path (Libraries are also known folders, so this will work)
			If librariesComboBox.SelectedIndex > -1 Then
				Dim selection As String = TryCast(librariesComboBox.SelectedItem, String)
				Dim selectedFolder As ShellContainer = Nothing

				Select Case selection
					Case "Documents"
						selectedFolder = TryCast(KnownFolders.DocumentsLibrary, ShellContainer)
					Case "Music"
						selectedFolder = TryCast(KnownFolders.MusicLibrary, ShellContainer)
					Case "Pictures"
						selectedFolder = TryCast(KnownFolders.PicturesLibrary, ShellContainer)
					Case "Videos"
						selectedFolder = TryCast(KnownFolders.VideosLibrary, ShellContainer)
						Exit Select
				End Select

				' Create a CommonOpenFileDialog
				Dim cfd As New CommonOpenFileDialog()
				cfd.CheckReadOnly = True

				' Set the initial location as the path of the library
				cfd.InitialLocation = selectedFolder

				If (Not cfd.ShowDialog().Canceled) Then
					' Get the selection from the user.
					Dim so As ShellObject = cfd.Item

					currentlySelected = so

					showChildItemsButton.Enabled = If(TypeOf so Is ShellContainer, True, False)

					DisplayProperties(so)
				End If
			End If
		End Sub

		Private Sub cfdFileButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles cfdFileButton.Click
			' Initialize
			detailsListView.Items.Clear()
			pictureBox1.Image = Nothing

			' Create a CommonOpenFileDialog to select files
			Dim cfd As New CommonOpenFileDialog()
			cfd.AllowNonFileSystemItems = True
			cfd.CheckReadOnly = True

			If (Not cfd.ShowDialog().Canceled) Then
				Dim selectedSO As ShellObject = Nothing

				Try
					' Try to get the selected item
					selectedSO = cfd.Item
				Catch
					MessageBox.Show("Could not create a ShellObject from the selected item")
				End Try

				currentlySelected = selectedSO

				' Set the path in our filename textbox
				selectedFileTextBox.Text = selectedSO.ParsingName

				DisplayProperties(selectedSO)

				showChildItemsButton.Enabled = If(TypeOf selectedSO Is ShellContainer, True, False)

			End If
		End Sub

		Private Sub cfdFolderButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles cfdFolderButton.Click
			' Initialize
			detailsListView.Items.Clear()
			pictureBox1.Image = Nothing

			' Display a CommonOpenFileDialog to select only folders 
			Dim cfd As New CommonOpenFileDialog()
			cfd.CheckReadOnly = True
			cfd.FoldersOnly = True
			cfd.AllowNonFileSystemItems = True

			If (Not cfd.ShowDialog().Canceled) Then
				Dim selectedSO As ShellContainer = Nothing

				Try
					' Try to get a valid selected item
					selectedSO = TryCast(cfd.Item, ShellContainer)
				Catch
					MessageBox.Show("Could not create a ShellObject from the selected item")
				End Try

				currentlySelected = selectedSO

				' Set the path in our filename textbox
				selectedFolderTextBox.Text = selectedSO.ParsingName

				DisplayProperties(selectedSO)

				showChildItemsButton.Enabled = If(TypeOf selectedSO Is ShellContainer, True, False)
			End If
		End Sub

		Private Sub savedSearchButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles savedSearchButton.Click
			' Initialize
			detailsListView.Items.Clear()
			pictureBox1.Image = Nothing

			' Display a CommonOpenFileDialog to select only folders 
			Dim cfd As New CommonOpenFileDialog()
			cfd.InitialDirectory = Path.Combine(KnownFolders.SavedSearches.Path, savedSearchComboBox.SelectedItem.ToString())
			cfd.CheckReadOnly = True

			If (Not cfd.ShowDialog().Canceled) Then
				Dim selectedSO As ShellObject = Nothing

				Try
					' Try to get a valid selected item
					selectedSO = cfd.Item
				Catch
					MessageBox.Show("Could not create a ShellObject from the selected item")
				End Try

				currentlySelected = selectedSO

				DisplayProperties(selectedSO)

				showChildItemsButton.Enabled = If(TypeOf selectedSO Is ShellContainer, True, False)

			End If
		End Sub

		Private Sub DisplayProperties(ByVal selectedSO As ShellObject)
			' Display some basic properties 
			If selectedSO IsNot Nothing Then
				' display properties for this folder, as well as a thumbnail image.
				selectedSO.Thumbnail.CurrentSize = New System.Windows.Size(128, 128)
				pictureBox1.Image = selectedSO.Thumbnail.Bitmap

				' show the properties
				AddProperty("Name", selectedSO.Name)
				AddProperty("Path", selectedSO.ParsingName)
				AddProperty("Type of ShellObject", selectedSO.GetType().Name)

				For Each prop As IShellProperty In selectedSO.Properties.DefaultPropertyCollection
					If prop.ValueAsObject IsNot Nothing Then
						Try
							AddProperty(prop.CanonicalName, prop.ValueAsObject.ToString())
						Catch
							' Ignore
							' Accessing some properties might throw exception.
						End Try
					End If
				Next prop
			End If

		End Sub

		Private Sub AddProperty(ByVal [property] As String, ByVal value As String)
			If (Not String.IsNullOrEmpty([property])) Then
				' Create the property ListViewItem
				Dim lvi As New ListViewItem([property])

				' Add a subitem for the value
				Dim subItemValue As New ListViewItem.ListViewSubItem(lvi, value)
				lvi.SubItems.Add(subItemValue)

				' Add the ListViewItem to our list
				detailsListView.Items.Add(lvi)
			End If
		End Sub

		Private Sub searchConnectorButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles searchConnectorButton.Click
			' Initialize
			detailsListView.Items.Clear()
			pictureBox1.Image = Nothing

			' Display a CommonOpenFileDialog to select only folders 
			Dim cfd As New CommonOpenFileDialog()
			cfd.InitialDirectory = Path.Combine(KnownFolders.SavedSearches.Path, searchConnectorComboBox.SelectedItem.ToString())
			cfd.CheckReadOnly = True

			If (Not cfd.ShowDialog().Canceled) Then
				Dim selectedSO As ShellObject = Nothing

				Try
					' Try to get a valid selected item
					selectedSO = cfd.Item
				Catch
					MessageBox.Show("Could not create a ShellObject from the selected item")
				End Try

				currentlySelected = selectedSO

				DisplayProperties(selectedSO)

				showChildItemsButton.Enabled = If(TypeOf selectedSO Is ShellContainer, True, False)

			End If
		End Sub

		Private Sub showChildItemsButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles showChildItemsButton.Click
			Dim container As ShellContainer = TryCast(currentlySelected, ShellContainer)

			If container Is Nothing Then
				Return
			End If

			Dim subItems As New SubItemsForm()

			' Populate
			For Each so As ShellObject In container
				subItems.AddItem(so.Name, so.Thumbnail.SmallBitmap)
			Next so

			subItems.ShowDialog()
		End Sub
	End Class
End Namespace